#!/usr/bin/env python3

import tkinter
from tkinter import ttk
root = tkinter.Tk()
root.title("pyturing")
menubar = tkinter.Menu(root)
root['menu'] = menubar
menu_tape = tkinter.Menu(menubar)
menu_table = tkinter.Menu(menubar)
menu_machine = tkinter.Menu(menubar)
menubar.add_cascade(menu=menu_tape, label='Tape')
menubar.add_cascade(menu=menu_table, label='Table')
menubar.add_cascade(menu=menu_machine, label='Machine')
import turing

class GUIMachine(turing.Machine, tkinter.Toplevel):
	def __init__(self, *args, **kwargs):
		turing.Machine.__init__(self, *args, **kwargs)
		tkinter.Toplevel.__init__(self)
		self.tapeString = tkinter.StringVar()
		self.tapeString.set(str(self.tape))
		self.statusString = tkinter.StringVar()
		self.statusString.set(str(self.currentState))
		self.title("Turing Machine")
		gf = ttk.Labelframe(self, text='Status')
		gf.pack()
		ttk.Label(gf, textvariable=self.statusString).pack()
		tf = ttk.Labelframe(self, text='Tape')
		tf.pack()
		ttk.Label(tf, textvariable=self.tapeString).pack()
		self.nextButton = ttk.Button(self, text="next", command=self.__next__)
		self.nextButton.pack()
	def __next__(self):
		try:
			super(GUIMachine, self).__next__()
			self.tapeString.set(str(self.tape))
			self.statusString.set(str(self.currentState))
			if not self.isRunning():
				self.nextButton['text'] = 'finished'
				self.nextButton.state(['disabled'])
		except:
			self.nextButton['text'] = 'error occurred'
			self.nextButton.state(['disabled'])

class GUITable(turing.Table, ttk.Frame):
	pass

class GUIInstruction(turing.Instruction, tkinter.Toplevel):
	def __init__(self, *args, **kwargs):
		turing.Instruction.__init__(self, *args, **kwargs)
		tkinter.Frame.__init__(self, *args, **kwargs)

table = turing.Table({
	's': {'a': ('p', 'a', turing.Tape.RIGHT), 'b': ('p', 'b', turing.Tape.RIGHT), 'B': ('q1', 'B', turing.Tape.LEFT)},
	'q1': {'a': ('q1', 'a', turing.Tape.LEFT), 'b': ('q1', 'b', turing.Tape.LEFT), 'B': ('q2', 'B', turing.Tape.RIGHT)},
	'q2': {'a': ('q2', 'a', turing.Tape.RIGHT), 'b': ('q3', 'b', turing.Tape.RIGHT), 'B': ('p', 'B', turing.Tape.LEFT)},
	'q3': {'a': ('p', 'a', turing.Tape.RIGHT), 'b': ('q3', 'b', turing.Tape.RIGHT), 'B': ('h', 'B', turing.Tape.LEFT)},
	'p': {'a': ('p', 'a', turing.Tape.RIGHT), 'b': ('p', 'b', turing.Tape.RIGHT), 'B': ('p', 'B', turing.Tape.LEFT)},
	'h': None,
})

tableStatus = tkinter.BooleanVar()
tapeStatus = tkinter.BooleanVar()
tapeContentString = tkinter.StringVar()
tapeDefaultValueString = tkinter.StringVar()

notebook = ttk.Notebook(root)
notebook.pack()

def checkTapeStatus(*args):
	try:
		turing.Tape(tapeDefaultValueString.get(), tapeContentString.get())
		if not tapeStatus.get():
			tapeStatus.set(True)
	except:
		if tapeStatus.get():
			tapeStatus.set(False)

tapeContentString.trace_variable('w', checkTapeStatus)

def checkStart(*args):
	if tapeStatus.get() and tableStatus.get():
		startButton.state(['!disabled'])
	else:
		startButton.state(['disabled'])

tapeStatus.trace_variable('w', checkStart)
tableStatus.trace_variable('w', checkStart)

tapeFrame = ttk.Frame(notebook)
notebook.add(tapeFrame, text="Tape")

ttk.Label(tapeFrame, text="Content").pack()
ttk.Entry(tapeFrame, textvariable=tapeContentString).pack()
ttk.Label(tapeFrame, text="Default value").pack()
ttk.Entry(tapeFrame, textvariable=tapeDefaultValueString).pack()

tableFrame = ttk.Frame(notebook)
notebook.add(tableFrame, text="Table")
ttk.Label(tableFrame, text="Here you can edit the transition table").pack()

graphFrame = ttk.Frame(notebook)
notebook.add(graphFrame, text="graph")
ttk.Label(graphFrame, text="Here you can see the graph").pack()

checkFrame = ttk.Labelframe(root, text='checks')
checkTable = ttk.Checkbutton(checkFrame, text='table ok', variable=tableStatus)
checkTable.state(['disabled'])
checkTable.pack()

checkTape = ttk.Checkbutton(checkFrame, text='tape ok', variable=tapeStatus)
checkTape.state(['disabled'])
checkTape.pack()
checkFrame.pack()

def createMachine():
	import copy
	GUIMachine(transition=copy.deepcopy(table), initialState='s', tape = turing.Tape(tapeDefaultValueString.get(), tapeContentString.get()))

startButton = ttk.Button(root, text="create machine", command=createMachine)
startButton.pack()

tapeContentString.set('abbb|B|')
tapeDefaultValueString.set('B')
tableStatus.set(True)
root.mainloop()
